/*
 * Part of the ACID Project
 * Developed in 2011 by Morgan Taschuk
 */
package acid.plugin.expression;

import acid.spring.db.GeneAlias;
import cytoscape.CyEdge;
import cytoscape.CyNode;
import cytoscape.Cytoscape;
import cytoscape.data.CyAttributes;
import cytoscape.task.Task;
import cytoscape.task.TaskMonitor;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *
 * @author morgan
 */
public class ShowExpressionCorrelations implements Task {

    private TaskMonitor taskMonitor;
    private double maxPVal;
    private double minFoldChange;
    private Map<String, Set<GeneAlias>> cyIdToGeneAlias;
    private ReadExpressionData red;

    public ShowExpressionCorrelations(ReadExpressionData red, double maxPVal, double minFoldChange) {
        this.maxPVal = maxPVal;
        this.minFoldChange = minFoldChange;
        this.red = red;
        this.cyIdToGeneAlias = red.getGeneAliases();
    }

    private void showAllExpressionCorrelations() {
        CyAttributes attrs = Cytoscape.getEdgeAttributes();

        List<CyEdge> edges = Cytoscape.getCyEdgesList();
        int counter = 1;
        for (CyEdge edge : edges) {
            CyNode s = (CyNode) edge.getSource();
            CyNode t = (CyNode) edge.getTarget();
            if (s.getIdentifier().equals(t.getIdentifier()))
                continue;

            Set<GeneAlias> sGA = cyIdToGeneAlias.get(s.getIdentifier());
            Set<GeneAlias> tGA = cyIdToGeneAlias.get(t.getIdentifier());

            if (sGA == null || tGA == null) {
                attrs.setAttribute(edge.getIdentifier(),
                        "expression_similarity", 0.0);
                continue;
            }

            double sim = red.getExpressionSimilarity(sGA, tGA, maxPVal, minFoldChange);

            if (sim != Double.MIN_VALUE) {
                attrs.setAttribute(edge.getIdentifier(),
                        "expression_similarity", sim);
            } else {
                attrs.setAttribute(edge.getIdentifier(),
                        "expression_similarity", 0.0);
            }
            taskMonitor.setPercentCompleted(Math.min(100, counter++ * 100 / edges.size()));
        }
        taskMonitor.setStatus("Redrawing graph...");
        Cytoscape.getCurrentNetworkView().redrawGraph(true, true);
    }

    /**
     * Get the value of maxPVal
     *
     * @return the value of maxPVal
     */
    public double getMaxPVal() {
        return maxPVal;
    }

    /**
     * Set the value of maxPVal
     *
     * @param maxPVal new value of maxPVal
     */
    public void setMaxPVal(double maxPVal) {
        this.maxPVal = maxPVal;
    }

    /**
     * Get the value of minFoldChange
     *
     * @return the value of minFoldChange
     */
    public double getMinFoldChange() {
        return minFoldChange;
    }

    /**
     * Set the value of minFoldChange
     *
     * @param minFoldChange new value of minFoldChange
     */
    public void setMinFoldChange(double minFoldChange) {
        this.minFoldChange = minFoldChange;
    }

    @Override
    public void run() {
        taskMonitor.setPercentCompleted(-1);

        taskMonitor.setStatus("Calculating expression correlations");
        showAllExpressionCorrelations();
        printBest();

    }

    private void printBest() {
        CyAttributes edgeAttrs = Cytoscape.getEdgeAttributes();
        CyAttributes nodeAttrs = Cytoscape.getNodeAttributes();

        List<CyEdge> edges = Cytoscape.getCyEdgesList();
        Collections.sort(edges, new Comparator<CyEdge>() {
            private CyAttributes attrs = Cytoscape.getEdgeAttributes();
            public int compare(CyEdge a, CyEdge b) {
                Double aES = attrs.getDoubleAttribute(a.getIdentifier(), "expression_similarity");
                Double bES = attrs.getDoubleAttribute(b.getIdentifier(), "expression_similarity");
                return aES.compareTo(bES);
            }
        });

        System.out.println("Start--");
        for (CyEdge e: edges)
        {
            String s = nodeAttrs.getStringAttribute(e.getSource().getIdentifier(), "canonicalName");
            String t = nodeAttrs.getStringAttribute(e.getTarget().getIdentifier(), "canonicalName");
            Double es = edgeAttrs.getDoubleAttribute(e.getIdentifier(), "expression_similarity");
            System.out.println(s + "\t" + t+ "\t" + es);
        }

    }

    @Override
    public void halt() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setTaskMonitor(TaskMonitor monitor) throws IllegalThreadStateException {
        taskMonitor = monitor;
    }

    @Override
    public String getTitle() {
        return "Overlay expression correlations";
    }
}
